package com.yfbao.horizon.demo;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.RemovalCause;
import com.github.benmanes.caffeine.cache.RemovalListener;
import com.yfbao.horizon.common.StatMonitUtil;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class StatMonitTest {

    private static String cachePrefix = "test-cahce-";
    private static Random random = new Random();

    private static Cache<String, Object> localCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).maximumSize(50000)
            .evictionListener(new RemovalListener<String, Object>() {
                @Override
                public void onRemoval(@Nullable String key, @Nullable Object value, RemovalCause cause) {
                    StatMonitUtil.moveCacheStat(key);
                }
            })
            .removalListener(new RemovalListener<String, Object>() {
                @Override
                public void onRemoval(@Nullable String key, @Nullable Object value, RemovalCause cause) {
                    StatMonitUtil.moveCacheStat(key);
                }
            })
            .recordStats().build();

    static {
        StatMonitUtil.cacheTotalStat(localCache, cachePrefix);
    }

    public static void main(String[] args) throws InterruptedException {
        testCacheStat();
        Thread.sleep(15*1000);
        testCycle();
        Thread.sleep(15*1000);
    }

    private static void testCacheStat(){
        initCache();
        int num = 0;
        while (true) {
            if (num > 10000) {
                break;
            }
            getCache();
            if(num%6%3>1){
                removeCache();
            }
            if(num%5>3){
                updateCache();
            }
            num++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("finished task");
    }

    private static void initCache() {
        for (int i = 0; i < 10000; i++) {
            String key = cachePrefix + random.nextInt(300);
            localCache.put(key, UUID.randomUUID().toString());
            StatMonitUtil.creatOrUpdCacheStat(key);
        }
        System.out.println("finished init cache");
    }

    private static void updateCache() {
        for (int i = 0; i < 100; i++) {
            String key = cachePrefix + random.nextInt(300);
            localCache.put(key, UUID.randomUUID().toString());
            StatMonitUtil.creatOrUpdCacheStat(key);
        }
        System.out.println("finished update cache");
    }

    private static void getCache() {
        for (int i = 0; i < 100; i++) {
            String key = cachePrefix + random.nextInt(500);
            Object o = localCache.getIfPresent(key);
            StatMonitUtil.readCacheStat(key);
        }
    }

    private static void removeCache() {
        for (int i = 0; i < 50; i++) {
            String key = cachePrefix + random.nextInt(500);
            localCache.invalidate(key);
        }
    }


    private static void testCycle(){
        List<Integer> list =new ArrayList<>();
        for(int i=0;i<1000;i++){
            list.add(i);
        }
        List<List<Integer>> listList = new ArrayList<>();
        for(int i=0;i<500;i++){
            listList.add(list);
        }
        StatMonitUtil.cycleMonit(listList);
        long cost1=0L;
        long cost2=0L;
        for(int j=0;j<10;j++){

//            long l = System.currentTimeMillis();
//            for(int i=0;i<50;i++){
//                StatMonitUtil.cycleMonit(list);
//            }
//            long l3 = System.currentTimeMillis() - l;
//            cost1 = cost1+(l3);
//            System.out.println("cost1:"+(l3));

            long l2 = System.currentTimeMillis();
            String loopKey = StatMonitUtil.getCycleKey();
            for(int i=0;i<50;i++){
                StatMonitUtil.cycleListMonit(loopKey,list);
            }
            long l1 = System.currentTimeMillis() - l2;
            cost2 = cost2+(l1);
            System.out.println("cost2:"+(l1));

        }
        System.out.println("cost1:"+cost1+"-----cost2:"+cost2);
    }

}
